package com.jeff.android.lab.architecture.mmkv;

import android.os.Parcelable;

import com.tencent.mmkv.MMKV;

import java.util.Set;

/**
 * @author: dingfeng
 * @date: 2020/12/18
 * @since: 1.0.0
 **/
public final class MmkvUtil {
    public static final String SIGN_KEY = "37698ee211c1081e9cb317d942783a1570cd1a3c371aa19e03e56c1f93b297cfce0a15d2aa537bbd4ba5d70cf7d44e757f3f8da5a9474e8d7192c948de9dec5d";

    private static MMKV defaultMMKV = null;

    public static MMKV getDefault() {
        if (null == defaultMMKV)
            defaultMMKV = MMKV.defaultMMKV();
        return defaultMMKV;
    }

    private static MMKV defaultCryptMMKV = null;

    public static MMKV getCryptMMKV() {
        if (null == defaultCryptMMKV)
            defaultCryptMMKV = MMKV.defaultMMKV(MMKV.SINGLE_PROCESS_MODE, SIGN_KEY);
        return defaultCryptMMKV;
    }

    /**************************************
     * put function
     **************************************/

    public static void putString(final String key, final String value) {
        putString(key, value, false);
    }

    public static void putBoolean(final String key, final boolean value) {
        putBoolean(key, value, false);
    }

    public static void putInt(final String key, final int value) {
        putInt(key, value, false);
    }

    public static void putLong(final String key, final long value) {
        putLong(key, value, false);
    }

    public static void putFloat(final String key, final float value) {
        putFloat(key, value, false);
    }

    public static void putDouble(final String key, final double value) {
        putDouble(key, value, false);
    }

    public static void putSet(final String key, final Set<String> value) {
        putSet(key, value, false);
    }

    public static void putBytes(final String key, final byte[] value) {
        putBytes(key, value, false);
    }

    public static void putParcelable(final String key, final Parcelable value) {
        putParcelable(key, value, false);
    }


    /**************************************
     * put function（加密）
     **************************************/
    public static void putString(final String key, final String value, final boolean encrypt) {
        if (encrypt)
            getCryptMMKV().encode(key, value);
        else
            getDefault().encode(key, value);
    }

    public static void putBoolean(final String key, final boolean value, final boolean encrypt) {
        if (encrypt)
            getCryptMMKV().encode(key, value);
        else
            getDefault().encode(key, value);
    }

    public static void putInt(final String key, final int value, final boolean encrypt) {
        if (encrypt)
            getCryptMMKV().encode(key, value);
        else
            getDefault().encode(key, value);
    }

    public static void putLong(final String key, final long value, final boolean encrypt) {
        if (encrypt)
            getCryptMMKV().encode(key, value);
        else
            getDefault().encode(key, value);
    }

    public static void putFloat(final String key, final float value, final boolean encrypt) {
        if (encrypt)
            getCryptMMKV().encode(key, value);
        else
            getDefault().encode(key, value);
    }

    public static void putDouble(final String key, final double value, final boolean encrypt) {
        if (encrypt)
            getCryptMMKV().encode(key, value);
        else
            getDefault().encode(key, value);
    }

    public static void putSet(final String key, final Set<String> value, final boolean encrypt) {
        if (encrypt)
            getCryptMMKV().encode(key, value);
        else
            getDefault().encode(key, value);
    }

    public static void putBytes(final String key, final byte[] value, final boolean encrypt) {
        if (encrypt)
            getCryptMMKV().encode(key, value);
        else
            getDefault().encode(key, value);
    }

    public static void putParcelable(final String key, final Parcelable value, final boolean encrypt) {
        if (encrypt)
            getCryptMMKV().encode(key, value);
        else
            getDefault().encode(key, value);
    }


    /**************************************
     * put function
     **************************************/

    public static String getString(final String key) {
        return getString(key, (String) null);
    }

    public static boolean getBoolean(final String key) {
        return getBoolean(key, false);
    }

    public static int getInt(final String key) {
        return getInt(key, 0);
    }

    public static long getLong(final String key) {
        return getLong(key, 0L);
    }

    public static float getFloat(final String key) {
        return getFloat(key, 0.0F);
    }

    public static double getDouble(final String key) {
        return getDouble(key, 0.0D);
    }

    public static Set<String> getSet(final String key) {
        return getSet(key, (Set<String>) null);
    }

    public static byte[] getBytes(final String key) {
        return getBytes(key, (byte[]) null);
    }

    public static <T extends Parcelable> T getParcelable(String key, Class<T> clazz) {
        return getParcelable(key, clazz, (T) null);
    }

    public static String getString(final String key, final String defaultValue) {
        return getDefault().decodeString(key, defaultValue);
    }

    public static boolean getBoolean(final String key, final boolean defaultValue) {
        return getDefault().decodeBool(key, defaultValue);
    }

    public static int getInt(final String key, final int defaultValue) {
        return getDefault().decodeInt(key, defaultValue);
    }

    public static long getLong(final String key, final long defaultValue) {
        return getDefault().decodeLong(key, defaultValue);
    }

    public static float getFloat(final String key, final float defaultValue) {
        return getDefault().decodeFloat(key, defaultValue);
    }

    public static double getDouble(final String key, final double defaultValue) {
        return getDefault().decodeDouble(key, defaultValue);
    }

    public static Set<String> getSet(final String key, final Set<String> defaultValue) {
        return getDefault().decodeStringSet(key, defaultValue);
    }

    public static byte[] getBytes(final String key, final byte[] defaultValue) {
        return getDefault().decodeBytes(key, defaultValue);
    }

    public static <T extends Parcelable> T getParcelable(String key, Class<T> clazz, final T defaultValue) {
        return getDefault().decodeParcelable(key, clazz, defaultValue);
    }


    /**************************************
     * put function（加密）
     **************************************/

    public static String getString(final String key, final boolean encrypt) {
        return getString(key, (String) null, encrypt);
    }

    public static boolean getBooleanEncrypt(final String key, final boolean encrypt) {
        return getBooleanEncrypt(key, false, encrypt);
    }

    public static int getInt(final String key, final boolean encrypt) {
        return getInt(key, 0, encrypt);
    }

    public static long getLong(final String key, final boolean encrypt) {
        return getLong(key, 0, encrypt);
    }

    public static float getFloat(final String key, final boolean encrypt) {
        return getFloat(key, 0.0F, encrypt);
    }

    public static double getDouble(final String key, final boolean encrypt) {
        return getDouble(key, 0.0D, encrypt);
    }

    public static Set<String> getSet(final String key, final boolean encrypt) {
        return getSet(key, (Set<String>) null, encrypt);
    }

    public static byte[] getBytes(final String key, final boolean encrypt) {
        return getBytes(key, (byte[]) null, encrypt);
    }

    public static <T extends Parcelable> T getParcelable(String key, Class<T> clazz, final boolean encrypt) {
        return getParcelable(key, clazz, (T) null, encrypt);
    }

    public static String getString(final String key, final String defaultValue, final boolean encrypt) {
        if (encrypt)
            return getCryptMMKV().decodeString(key, defaultValue);
        return getDefault().decodeString(key, defaultValue);
    }

    public static boolean getBooleanEncrypt(final String key, final boolean defaultValue, final boolean encrypt) {
        if (encrypt)
            return getCryptMMKV().decodeBool(key, defaultValue);
        return getDefault().decodeBool(key, defaultValue);
    }

    public static int getInt(final String key, final int defaultValue, final boolean encrypt) {
        if (encrypt)
            return getCryptMMKV().decodeInt(key, defaultValue);
        return getDefault().decodeInt(key, defaultValue);
    }

    public static long getLong(final String key, final long defaultValue, final boolean encrypt) {
        if (encrypt)
            return getCryptMMKV().decodeLong(key, defaultValue);
        return getDefault().decodeLong(key, defaultValue);
    }

    public static float getFloat(final String key, final float defaultValue, final boolean encrypt) {
        if (encrypt)
            return getCryptMMKV().decodeFloat(key, defaultValue);
        return getDefault().decodeFloat(key, defaultValue);
    }

    public static double getDouble(final String key, final double defaultValue, final boolean encrypt) {
        if (encrypt)
            return getCryptMMKV().decodeDouble(key, defaultValue);
        return getDefault().decodeDouble(key, defaultValue);
    }

    public static Set<String> getSet(final String key, final Set<String> defaultValue, final boolean encrypt) {
        if (encrypt)
            return getCryptMMKV().decodeStringSet(key, defaultValue);
        return getDefault().decodeStringSet(key, defaultValue);
    }

    public static byte[] getBytes(final String key, final byte[] defaultValue, final boolean encrypt) {
        if (encrypt)
            return getCryptMMKV().decodeBytes(key, defaultValue);
        return getDefault().decodeBytes(key, defaultValue);
    }

    public static <T extends Parcelable> T getParcelable(String key, Class<T> clazz, final T defaultValue, final boolean encrypt) {
        if (encrypt)
            return getCryptMMKV().decodeParcelable(key, clazz, defaultValue);
        return getDefault().decodeParcelable(key, clazz, defaultValue);
    }

}
